Description of the algorithm for next_permutation:
Find largest index i such that array[i − 1] < array[i]. (If no such i exists, then this is already the last permutation.)
Find largest index j such that j ≥ i and array[j] > array[i − 1].
Swap array[j] and array[i − 1].
Reverse the suffix starting at array[i].
In [1]:
def next_permutation(perm):
n = len(perm)
# Find longest non-increasing suffix
i = n - 1
while i > 0 and perm[i - 1] >= perm[i]:
i -= 1
# Is this the last permutation?
if i <= 0:
return False
# perm[i - 1] is the pivot
# search for the rightmost j such that perm[j] > perm[i - 1]
j = n - 1
while perm[j] <= perm[i - 1]:
j -= 1
assert j >= i
# perm[j] will become the new pivot (swap perm[i-1] and perm[j])
perm[i - 1], perm[j] = perm[j], perm[i - 1]
# reverse the suffix perm[i..j]
perm[i:j+1] = perm[i:j+1][::-1]
return True
# generator for all permutations
def permutations(perm):
is_next = True
while is_next:
yield perm
is_next = next_permutation(perm)
In [3]:
p = [1, 3, 2, 4]
print(next_permutation(p), p)
In [4]:
p = [2, 4, 3, 7, 6, 8, 9, 5, 1, 0]
print(next_permutation(p), p)
In [5]:
for p in permutations(list(range(4))):
print(p)
In [6]:
p = ['a', 'l', 'e', 'x']
print(next_permutation(p), p)